OBJECTID PROGRAM_NAME ... EDITED geometry
0 1 Shepherd Park Library ... None POINT (-77.02704 38.98029)
1 2 Takoma Library ... None POINT (-77.02016 38.97444)
2 3 Headquarters ... None POINT (-77.02706 38.96692)
3 4 Chevy Chase Library ... None POINT (-77.07546 38.96558)
4 5 Lamond-Riggs Library ... None POINT (-76.99959 38.95514)
[5 rows x 69 columns]
type(homeless_facilities)
<class 'geopandas.geodataframe.GeoDataFrame'>
homeless_facilities.geometry
0 POINT (-77.02704 38.98029)
1 POINT (-77.02016 38.97444)
2 POINT (-77.02706 38.96692)
3 POINT (-77.07546 38.96558)
4 POINT (-76.99959 38.95514)
...
110 POINT (-76.98065 38.84928)
111 POINT (-76.98125 38.84619)
112 POINT (-76.97423 38.8436)
113 POINT (-77.00937 38.83133)
114 POINT (-77.00815 38.82999)
Name: geometry, Length: 115, dtype: geometry
Obtaining background layers
For street-map type layers, contextily package is one resource
For Census tract/county/state layers, can either obtain shapefiles from Census API directly or use pygris, similar to R’s tigris
See that similar to sf in R, geopandas helps maintain it as a spatial dataframe post merge
dc_tracts_wpov = dc_tracts.merge(dc_poverty_info, how ="inner", on ="GEOID")type(dc_tracts_wpov)
<class 'geopandas.geodataframe.GeoDataFrame'>
Plotting the result
See here for a list of colormap (cmap) options: link here
fig, ax = plt.subplots()dc_tracts_wpov.plot(edgecolor ="black", alpha =0.9, ax = ax, column ="DP03_0119PE", legend =True, cmap ="Blues")homeless_tractcrs.plot(ax = ax, marker ="o", color ="red", markersize =0.5)ax.set_axis_off()plt.title("Homeless facilities in DC vs. % of tract living in poverty",color ="white")fig.patch.set_visible(False)plt.show()
Plotting the result
Where we are
Static plots with geopandas
Two types of background layers: street maps + census data
Spatial joins/intersections
Interactive plotting with folium
Spatial intersection
Previous example was merging a spatial dataframe with a non-spatial attribute using a GEOID column
How can we do a spatial intersection where we find the count of homeless facilities within each tract?
Unlike intersects and intersection in R, which check all elements against each other, the equivalent operations in python only check pairs of rows
If want to avoid iteration, can use the sjoin command
## group the dataframe to find the count in tracts with 1+ overlapcount_pertract_1plus = tracts_w_facilities.groupby('GEOID').size().\ reset_index() count_pertract_1plus.columns = ["GEOID", "count_facilities"]## create a similar dataframe with the tracts that had## no intersections with a facility (so count = 0)nonjoined_tracts =set(dc_tracts_wpov.GEOID).\ difference(tracts_w_facilities.GEOID)count_pertract_zero = pd.DataFrame({'GEOID': list(nonjoined_tracts),'count_facilities': 0}) count_pertract_all = pd.concat([count_pertract_1plus, count_pertract_zero])assert count_pertract_all.shape[0] ==\len(count_pertract_all.GEOID.unique())## merge back using GEOIDdc_tracts_wcount = dc_tracts.merge(count_pertract_all, how ="inner", on ="GEOID")
Step three: plot the results with a categorical shading
fig, ax = plt.subplots()dc_tracts_wcount.plot(edgecolor ="black", alpha =0.9, ax = ax, column ="count_facilities", categorical =True, legend =True, cmap ="Blues")ax.set_axis_off()plt.title("Count of homeless facilities per DC census tract", color ="white")fig.patch.set_visible(False)plt.show()
Step three: plot the results with a categorical shading
Where we are
Static plots with geopandas
Two types of background layers: street maps + census data
Spatial joins/intersections
Interactive plotting with folium
Folium for interactive plotting
Wrapper for leaflet which we covered in R
Similar capabilities including zoom and hoverable/clickable markers and shapes
Step one: create the background map
Default is open street map
m = folium.Map(location = [38.9047, -77.016], zoom_start =12)m
Make this Notebook Trusted to load map: File -> Trust Notebook
Example one: add markers with hoverable + clickable information
Tooltips: pull up information as you hover over a marker/point
Popups: pull up information as you click on a marker/point - can also add the ability to zoom in on that point
The geoJson set of commands within folium can accept either geojson or geopandas dataframes for plotting
Example one: add markers with hoverable + clickable information